import sys

from PyQt5.QtCore import QRect, QPointF
from PyQt5.QtGui import QBrush, QLinearGradient, QColor, QPen, QTextOption, QFontMetrics
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication

# window_height = 10
# self.begin_width_spacing = 15    # 最开始时距离左右边框的位置
# self.begin_height_spacing = 16   # 最开始时距离上边框的位置
# self.icon_width = 40             # Icon宽度
# self.icon_height = 40            # Icon高度
# self.text_width_spacing = 12     # 字体内容距离气泡左右边框的距离
# self.self.text_height_spacing = 12    # 字体内容距离气泡上下边框的距离
# self.triangle_width = 6          # 三角形的宽度
# self.triangle_height = 10        # 三角形的高度
# self.triangle_height_spacing = 10
# self.text_self.min_width = 0
# self.min_width = 0
# self.text_max_width = 0
# self.real_width = 0
# self.text_height = 0


class MyWidget(QtWidgets.QWidget):
    def __init__(self, parent=None, data='', type_mess=0):
        super(MyWidget, self).__init__(parent)
        self.setObjectName('myWidget')
        self.user_chat_content = data
        self.type_mess = type_mess
        self.resize(500, 75)

        self.window_height = 10
        self.begin_width_spacing = 15  # 最开始时距离左右边框的位置
        self.begin_height_spacing = 16  # 最开始时距离上边框的位置
        self.icon_width = 40  # Icon宽度
        self.icon_height = 40  # Icon高度
        self.text_width_spacing = 12  # 字体内容距离气泡左右边框的距离
        self.text_height_spacing = 12  # 字体内容距离气泡上下边框的距离
        self.triangle_width = 6  # 三角形的宽度
        self.triangle_height = 10  # 三角形的高度
        self.triangle_height_spacing = 10
        self.text_min_width = 0
        self.min_width = 0
        self.text_max_width = 0
        self.real_width = 0
        self.text_height = 0

    # 重写paintEvent 否则不能使用样式表定义外观
    def paintEvent(self, event):
        self.init_data()
        # global self.text_self.min_width, self.min_width, self.text_max_width, self.real_width, self.text_height, self.window_height
        # 初始化QPainter对象，一支画笔
        painter = QtGui.QPainter(self)
        painter.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform)
        font = QtGui.QFont()
        font.setFamily("实体")
        font.setPointSize(12)
        painter.setFont(font)
        # 画头像
        icon_rect = QRect(self.begin_width_spacing, self.begin_height_spacing, self.icon_width, self.icon_height)
        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(QBrush(QtCore.Qt.gray))
        painter.drawPixmap(icon_rect, QtGui.QPixmap("boy.png"))
        # 画框架
        bubbleRect = QRect(self.begin_width_spacing + self.icon_width, self.begin_height_spacing,
                           self.triangle_width + self.text_width_spacing + self.text_max_width + self.text_width_spacing,
                           self.text_height_spacing + self.text_height + self.text_height_spacing)
        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(QBrush(QColor(180, 180, 180)))
        painter.drawRoundedRect(bubbleRect.x() + self.triangle_width, bubbleRect.y(), bubbleRect.width() - self.triangle_width,
                                bubbleRect.height(), 18, 18)
        # QLinearGradient((x1,y1),(x2,y2))：点(x1,y1)到点(x2,y2)的渐变
        linearGradient = QLinearGradient(QPointF(bubbleRect.x() + self.triangle_width + 1, bubbleRect.y() + 1),
                                         QPointF(bubbleRect.x() + bubbleRect.width() - 1,
                                                 bubbleRect.y() + bubbleRect.height() - 1))
        linearGradient.setColorAt(0, QColor(151, 220, 227))
        linearGradient.setColorAt(0.25, QColor(151, 220, 227))
        linearGradient.setColorAt(0.5, QColor(151, 220, 227))
        linearGradient.setColorAt(0.75, QColor(151, 220, 227))
        linearGradient.setColorAt(1, QColor(151, 220, 227))

        painter.setBrush(linearGradient)

        painter.drawRoundedRect(bubbleRect.x() + self.triangle_width + 1, bubbleRect.y() + 1,
                                bubbleRect.width() - self.triangle_width - 2, bubbleRect.height() - 2, 18, 18)
        painter.setPen(QPen(QColor(244, 164, 96)))
        painter.drawPolygon(QPointF(bubbleRect.x(), bubbleRect.y() + self.triangle_height_spacing - 4),
                            QPointF(bubbleRect.x() + self.triangle_width + 1, bubbleRect.y() + self.triangle_height_spacing),
                            QPointF(bubbleRect.x() + 6 + 1, bubbleRect.y() + 10 + 10))

        painter.setPen(QPen(QColor(180, 180, 180)))
        painter.drawLine(QPointF(bubbleRect.x(), bubbleRect.y() + 10 - 4),
                         QPointF(bubbleRect.x() + 6, bubbleRect.y() + 10))
        painter.drawLine(QPointF(bubbleRect.x(), bubbleRect.y() + 10 - 4),
                         QPointF(bubbleRect.x() + 6, bubbleRect.y() + 10 + 10))
        # 画文字
        penText = QPen()
        penText.setColor(QColor(56, 56, 56))
        painter.setPen(penText)
        option = QTextOption(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
        # WrapAtWordBoundaryOrAnywhere：尽可能赶在单词的边界, 否则就在任意位置换行
        option.setWrapMode(QTextOption.WrapAtWordBoundaryOrAnywhere)
        painter.drawText(
            QtCore.QRectF(bubbleRect.x() + self.triangle_width + self.text_width_spacing, bubbleRect.y() + self.text_height_spacing,
                   self.text_max_width, self.text_height), self.user_chat_content, option)

    def init_data(self):
        """ 此函数用于初始化边框参数 """
        font = QtGui.QFont()
        font.setFamily("实体")
        font.setPointSize(12)
        # 提供关于字体的指标信息,QFontMetrics的函数用于计算给定字体的字符和字符串的大小
        metrics = QtGui.QFontMetrics(font)
        # global self.text_self.min_width, self.min_width, self.text_max_width, self.real_width, self.text_height, self.window_height
        if metrics.width("A") * 2 + self.begin_height_spacing * 1.5 > self.text_width_spacing:
            self.text_min_width = self.begin_height_spacing * 1.5 - self.text_width_spacing
        else:
            self.text_min_width = 0
        self.min_width = self.begin_width_spacing + self.icon_width + self.triangle_width + self.text_width_spacing + self.text_width_spacing + self.icon_width + self.begin_width_spacing
        # print("***********")
        # print(self.min_width)
        # print(self.text_self.min_width)
        # print(self.width())
        if self.width() < self.min_width + self.text_min_width:
            self.setMinimumWidth(self.min_width + self.text_min_width)
        self.text_max_width = self.width() - self.min_width

        self.real_width = metrics.width(self.user_chat_content)
        # print("height:", metrics.height())
        if self.real_width < self.text_max_width:
            self.text_max_width = self.real_width
            if self.text_height_spacing + metrics.height() + self.text_height_spacing > self.triangle_height_spacing + self.triangle_height + self.triangle_height_spacing:
                self.text_height = metrics.height()
            else:
                self.text_height = self.triangle_height_spacing + self.triangle_height + self.triangle_height_spacing
        else:
            flag = QtCore.Qt.TextWordWrap
            textRect = QtCore.QRect(0, 0, self.text_max_width, 0)
            # 自动换行
            textRect = metrics.boundingRect(textRect, flag, self.user_chat_content)
            self.text_height = textRect.height()


# class MyListWidget(QtWidgets.QListWidget):
#     def __init__(self):
#         super().__init__()
#
#     def paintEvent(self, e: QtGui.QPaintEvent) -> None:
#         pass


class Win(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.resize(800, 400)
        self.item_count = 0

        self.central_widget = QtWidgets.QListWidget(self)
        self.central_widget.setObjectName("central_widget")
        self.setCentralWidget(self.central_widget)
        self.central_widget.setStyleSheet("#central_widget::item{"
                                          "background-color:transparent;"
                                          "border:transparent};"
                                          "#central_widget::item:hover{"
                                          "background-color:transparent};"
                                          "#central_widget::item:selected{"
                                          "background-color:transparent};"
                                          "#central_widget{border:1px solid red;}")
        context = "this is a first dialog with AI,I don't know how to talk with it!"
        self.add_item(context)
        self.add_item(context)
        self.add_item(context)
        self.add_item(context)

    # def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
    #     print(self.central_widget.size())
    #     size = self.central_widget.size()
    #     height = size.height()
    #     width = size.width()
    #     if size.width()
    # 1 row 805
    # 2 row 483
    # 3 row 385

    def add_item(self, context):

        item_widget = MyWidget(data=context)
        height = item_widget.height()
        # height = self.text_height*2+self.text_width_spacing*2+self.begin_height_spacing*2
        print(height)

        item = QtWidgets.QListWidgetItem()
        # height = self.item_count * 10
        item.setSizeHint(QtCore.QSize(300, height))
        self.item_count += 1

        self.central_widget.addItem(item)
        self.central_widget.setItemWidget(item, item_widget)


# class TestWin(QtWidgets.QMainWindow):
#     def __init__(self, parent=None):
#         super().__init__(parent=parent)
#         self.resize(800, 400)
#
#         self.scrollArea = QtWidgets.QScrollArea(self)
#         self.scrollArea.setObjectName("scrollArea")
#         self.setCentralWidget(self.scrollArea)
#         self.scrollArea.setStyleSheet("#scrollArea{border:1px solid blue;}")
#
#         self.hlayout = QtWidgets.QHBoxLayout(self.scrollArea)
#         self.hlayout.setObjectName("hlayout")
#
#         self.central_widget = QtWidgets.QFrame(self.scrollArea)
#         self.central_widget.resize(700,300)
#         # self.central_widget.setMinimumSize(700, 330)
#         self.central_widget.setObjectName("central_widget")
#         self.central_widget.setStyleSheet("#central_widget{border:1px solid red;}")
#
#         self.hlayout.addWidget(self.central_widget)
#
#         self.vlayout = QtWidgets.QVBoxLayout(self.central_widget)
#         self.vlayout.setObjectName("vlayout")
#         self.vlayout.setSpacing(10)
#
#         self.scrollArea.setWidget(self.central_widget)
#
#         self.add_item()
#         self.add_item()
#         self.add_item()
#         self.add_item()
#
#     def add_item(self):
#         # item = QtWidgets.QWidget()
#
#         context = "this is a first dialog with AI,I don't know how to talk with it!"
#         item_widget = MyWidget(data=context)
#         self.vlayout.addWidget(item_widget)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    # win = MyWidget(data="this is a first dialog with AI,I don't know how to talk with it!", type_mess=1)
    win = Win()
    # win = TestWin()
    win.show()
    sys.exit(app.exec_())
